﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace M1Xonix
{
    class HighScoreScreen : GameScreen
    {
        const int HighscorePlaces = 10;
        public const string PlayerNamePlaceholder = "<player>";
        const string DefaultPlayerName = "Player";
        private int _newPosition = -1;

        private KeyValuePair<string, int>[] _highScore = new KeyValuePair<string, int>[HighscorePlaces]
            {
                new KeyValuePair<string, int>("Richard Stallman", 100000),
                new KeyValuePair<string, int>("Tim Berners-Lee", 90000),
                new KeyValuePair<string, int>("Linus Torvalds", 80000),
                new KeyValuePair<string, int>("Bill Gates", 70000),
                new KeyValuePair<string, int>("Ada Lovelace", 60000),
                new KeyValuePair<string, int>("Alan Turing", 50000),
                new KeyValuePair<string, int>("James Gosling", 40000),
                new KeyValuePair<string, int>("Steve Wozniak", 30000),
                new KeyValuePair<string, int>("David Heinemeier Hansson", 20000),
                new KeyValuePair<string, int>("Alexey Pajitnov", 10000)
            };

        public HighScoreScreen()
        {
            LoadHighscore();
        }

        public HighScoreScreen(int score)
        {
            LoadHighscore();
            if (IsInHighscores(score))
            {
                // Guide.BeginShowKeyboardInput(PlayerIndex.One, "Enter your name: ", "You have a high score!", DefaultPlayerName, GetInput, score);
                string envuser = Environment.UserName;
                PutHighScore(string.IsNullOrWhiteSpace(envuser) ? DefaultPlayerName : envuser, score);
            }
        }

        //private void GetInput(IAsyncResult r)
        //{
        //    string playerName = Guide.EndShowKeyboardInput(r);

        //    if (playerName != null && playerName.Length > 15)
        //        playerName = playerName.Substring(0, 15);
        //    else if (string.IsNullOrEmpty(playerName))
        //    {
        //        playerName = DefaultPlayerName;
        //    }
        //    PutHighScore(playerName, (int)r.AsyncState);
        //}

        public override void HandleInput(InputState input)
        {
            KeyboardState keys = input.CurrentKeyboardStates[(int)ControllingPlayer.Value];
            GamePadState pad = input.CurrentGamePadStates[(int)ControllingPlayer.Value];

            if (pad.IsButtonDown(Buttons.Start) || pad.IsButtonDown(Buttons.Back) || keys.IsKeyDown(Keys.Space) || keys.IsKeyDown(Keys.Escape))
            {
                ExitScreen();
                ScreenManager.AddScreen(new BackgroundScreen(), null);
                ScreenManager.AddScreen(new MainMenuScreen(), null);
            }
        }

        public override void Draw(GameTime gameTime)
        {
            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
            SpriteFont font = ScreenManager.Font;

            spriteBatch.Begin();
            spriteBatch.DrawString(font, "High Scores", new Vector2(30, 30), Color.White);
            spriteBatch.DrawString(font, "Press <Esc> or <Back> to continue", new Vector2(400, 600), Color.Red);

            // Draw the highscores table
            for (int i = 0; i < _highScore.Length; i++)
            {
                Color textColor = Color.YellowGreen;
                if (i == _newPosition)
                {
                    textColor = Color.Orange;
                }
                spriteBatch.DrawString(font, String.Format("{0}. {1}", i + 1, _highScore[i].Key), new Vector2(100, i * 40 + 70), textColor);
                spriteBatch.DrawString(font, String.Format("{0}", _highScore[i].Value), new Vector2(600, i * 40 + 70), textColor);
            }

            spriteBatch.End();

            base.Draw(gameTime);
        }

        public bool IsInHighscores(int score)
        {
            // If the score is less from the last place score
            return score > _highScore[HighscorePlaces - 1].Value;
        }

        private void OrderGameScore()
        {
            _highScore = (_highScore.OrderByDescending(e => e.Value)).ToArray();
        }

        public void PutHighScore(string playerName, int score)
        {
            _newPosition = -1;
            if (IsInHighscores(score))
            {
                _highScore[HighscorePlaces - 1] = new KeyValuePair<string, int>(playerName, score);
                OrderGameScore();
                for (int i = 0; i < _highScore.Length; i++)
                {
                    var highScore = _highScore[i];
                    if (playerName.Equals(highScore.Key) && score == highScore.Value)
                    {
                        _newPosition = i;
                    }
                }
                SaveHighscore();
            }
        }

        public void SaveHighscore()
        {
            RegistryKey key = Registry.CurrentUser.CreateSubKey("Software\\M1Xonix");
            var scores = new string[HighscorePlaces];
            for (int i = 0; i < _highScore.Length; i++)
            {
                var highScore = _highScore[i];
                scores[i] = highScore.Key + "," + highScore.Value;
            }
            string scoreString = String.Join(";", scores);
            key.SetValue("Highscores", scoreString);
            key.Close();
        }

        public void LoadHighscore()
        {
            RegistryKey key = Registry.CurrentUser.OpenSubKey("Software\\M1Xonix");
            if (key != null)
            {
                string highScoresString = key.GetValue("Highscores") as string;
                key.Close();

                string[] lines = highScoresString.Split(';');

                for (int i = 0; i < lines.Length; i++)
                {
                    var row = lines[i];
                    string[] fields = row.Split(',');
                    _highScore[i] = new KeyValuePair<string, int>(fields[0], int.Parse(fields[1]));
                }
                OrderGameScore();
            }
        }
    }

}
